/*
 *  This file is part of BBBFlashCard.
 *
 *  BBBFlashCard is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  BBBFlashCard is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with BBBFlashCard.  If not, see <http://www.gnu.org/licenses/>.
 */
package hu.bbb.flashcard.model;


import java.io.UnsupportedEncodingException;
import net.sourceforge.floggy.persistence.Nameable;
import net.sourceforge.floggy.persistence.Persistable;

/**
 *
 * @author bsudy
 */
public class FlashCard  implements Persistable, Nameable {

    private String sideA;
    private String sideB;

    private int deck = 0;
    private int lastSuccess = 0;

    private int reverseDeck = 0;
    private int lastReverseSuccess = 0;

    public FlashCard(String sideA, String sideB) {
        this.sideA = sideA;
        this.sideB = sideB;
    }

    public FlashCard(String sideA, String sideB, int deck, int lastSuccess, int reverseDeck, int lastReverseSuccess) {
        this.sideA = sideA;
        this.sideB = sideB;
        this.deck = deck;
        this.lastSuccess = lastSuccess;
        this.reverseDeck = reverseDeck;
        this.lastReverseSuccess = lastReverseSuccess;
    }



    public int getDeck(boolean reverse) {
        if (reverse) {
            return reverseDeck;
        }
        return deck;
    }

    public int getLastSuccess(boolean reverse) {
        if (reverse) {
            return lastReverseSuccess;
        }
            return lastSuccess;
    }

    public String getSideA() {
        return sideA;
    }

    public String getSideB() {
        return sideB;
    }

    public void success(int sessionNumber, boolean reverse) {
        System.out.println("Success:" + sideA + " " + sessionNumber);
        if (reverse) {
            reverseDeck ++;
            lastReverseSuccess = sessionNumber;
        } else {
            deck ++;
            lastSuccess = sessionNumber;
        }
    }

    public void failure(boolean reverse) {
        System.out.println("failure:" + sideA);
        if (reverse) {
            reverseDeck = 0;
        } else {
            deck = 0;
        }

    }

    public String getRecordStoreName() {
        return "flashcard";
    }


    public byte[] getBytes() throws UnsupportedEncodingException {

        byte[] sideABytes = sideA.getBytes("UTF-8");
        byte[] sideASizeBytes = intToByte(sideABytes.length);
        byte[] sideBBytes = sideB.getBytes("UTF-8");
        byte[] sideBSizeBytes = intToByte(sideBBytes.length);
        
        byte[] deckBytes = intToByte(deck);
        byte[] lastSuccessBytes = intToByte(lastSuccess);
        byte[] reverseDeckBytes = intToByte(reverseDeck);
        byte[] reverseLastSuccessBytes = intToByte(lastReverseSuccess);
        
        
        int length = sideASizeBytes.length +
                sideABytes.length + 
                sideBSizeBytes.length + 
                sideBBytes.length +
                deckBytes.length +
                lastSuccessBytes.length +
                reverseDeckBytes.length +
                reverseLastSuccessBytes.length;

        byte[] ret = new byte[length];
        int pos = 0;
        System.arraycopy(sideASizeBytes, 0, ret, pos, sideASizeBytes.length);
        pos += sideASizeBytes.length;

        System.arraycopy(sideABytes, 0, ret, pos, sideABytes.length);
        pos += sideABytes.length;

        System.arraycopy(sideBSizeBytes, 0, ret, pos, sideBSizeBytes.length);
        pos += sideBSizeBytes.length;

        System.arraycopy(sideBBytes, 0, ret, pos, sideBBytes.length);
        pos += sideBBytes.length;

        System.arraycopy(deckBytes, 0, ret, pos, deckBytes.length);
        pos += deckBytes.length;

        System.arraycopy(lastSuccessBytes, 0, ret, pos, lastSuccessBytes.length);
        pos += lastSuccessBytes.length;

        System.arraycopy(reverseDeckBytes, 0, ret, pos, reverseDeckBytes.length);
        pos += reverseDeckBytes.length;

        System.arraycopy(reverseLastSuccessBytes, 0, ret, pos, reverseLastSuccessBytes.length);
        pos += reverseLastSuccessBytes.length;

        return ret;
    }



    public static byte[] intToByte(final int i) {
        final byte[] bytes = new byte[4];
        bytes[0] =(byte)( i >> 24 );
        bytes[1] =(byte)( i << 8 >> 24 );
        bytes[2] =(byte)( i << 16 >> 24 );
        bytes[3] =(byte)( i << 24 >> 24 );
        return bytes;
    }

    public static int byteToInt(final byte[] b) {
        int i = 0;
        i |= b[0] & 0xFF;
        i <<= 8;
        i |= b[1] & 0xFF;
        i <<= 8;
        i |= b[2] & 0xFF;
        i <<= 8;
        i |= b[3] & 0xFF;
        return i;
    }

    public static FlashCard parseBytes(byte[] bytes) throws UnsupportedEncodingException {

        

        
        byte[] sideASizeBytes = new byte[4];
        
        byte[] sideBSizeBytes = new byte[4];

        byte[] deckBytes = new byte[4];
        byte[] lastSuccessBytes = new byte[4];
        byte[] reverseDeckBytes = new byte[4];
        byte[] reverseLastSuccessBytes = new byte[4];


        int pos = 0;
        System.arraycopy(bytes, pos, sideASizeBytes, 0, 4);
        pos += 4;
        int sideASize = byteToInt(sideASizeBytes);

        byte[] sideABytes = new byte[sideASize];
        System.arraycopy(bytes, pos, sideABytes, 0, sideASize);
        pos += sideASize;

        System.arraycopy(bytes, pos, sideBSizeBytes, 0, 4);
        pos += 4;
        int sideBSize = byteToInt(sideBSizeBytes);

        byte[] sideBBytes = new byte[sideBSize];
        System.arraycopy(bytes, pos, sideBBytes, 0, sideBSize);
        pos += sideBSize;

        System.arraycopy(bytes, pos, deckBytes, 0, 4);
        pos += 4;

        System.arraycopy(bytes, pos, lastSuccessBytes, 0, 4);
        pos += 4;

        System.arraycopy(bytes, pos, reverseDeckBytes, 0, 4);
        pos += 4;

        System.arraycopy(bytes, pos, reverseLastSuccessBytes, 0, 4);
        pos += 4;

        String sideA = new String(sideABytes, "UTF-8");
        String sideB = new String(sideBBytes, "UTF-8");

        int deck = byteToInt(deckBytes);
        int lastSuccess = byteToInt(lastSuccessBytes);

        int reverseDeck = byteToInt(reverseDeckBytes);
        int lastReverseSuccess = byteToInt(reverseLastSuccessBytes);

        return new FlashCard(sideA, sideB, deck, lastSuccess, reverseDeck, lastReverseSuccess);
    }

    public boolean isKnown(final Boolean mode) {
        if (mode == null) {
            return deck > 4 && reverseDeck > 4;
        } else if (mode.booleanValue()) {
            return deck > 4;
        } else {
            return reverseDeck > 4;
        }
    }

}
